Prepare Your Data
Pre-conditions
If you’ve followed the steps in the previous sections, you should have a copy of the code and be able to run it with an error on renderChart. If not, please revisit the previous lessons to get set up.
Create a Data Model from input data
The data model is unique to every chart. It defines how each point will be plotted on the chart. In this step we will deal with thoughtspot ChartModel to create dataModel and feed that dataModel to to new Charts in render function that we will be create in next step in chart.js required format.
Let's create dataModel with the following steps:
- Create the function
getDataModelthat will takechartModeland returncolumnchartModelobject. Code snippet is as follow-
function getDataModel(
chartModel: ChartModel,
customStyleConfig: ChartSdkCustomStylingConfig | undefined
) {
// column chart model
const columnChartModel = getColumnDataModel(
chartModel.config?.chartConfig?.[0].dimensions ?? [],
chartModel.data?.[0].data ?? [],
"bar",
chartModel.visualProps,
customStyleConfig
);
return columnChartModel;
}
- Create two global array that will have with name
availableColorandvisualPropKeyMapthat will be used to provide default color configurations and mapping key value pair that we will be getting from invisualProp. The code snippet is as follow-
Chart.register(ChartDataLabels);
let globalChartReference: Chart;
const availableColor = ["red", "green", "blue"];
const visualPropKeyMap = {
0: "color",
1: "accordion.Color2",
2: "accordion.datalabels",
};
- In this we will be implementing
getColumnDataModelthat is there ingetDataModel. This willchartConfig,chartData(data),typeandvisualprop(current prop key and value) and return object with function such asgetLabel,getDatasets(axisId,type,colorConfiguration),getScales(chart.js display configurations) andgetPointDetails. Code snippet is given below-
function getColumnDataModel(
configDimensions,
dataArr: DataPointsArray,
type,
visualProps: VisualProps
) {
// this should be handled in a better way
const xAxisColumns = configDimensions?.[0].columns ?? [];
const yAxisColumns = configDimensions?.[1].columns ?? [];
return {
getLabels: () => getDataForColumn(xAxisColumns[0], dataArr),
getDatasets: () =>
_.map(yAxisColumns, (col, idx) => {
const coldata = getDataForColumn(col, dataArr);
const CFforColumn = getCfForColumn(col);
const axisId = `${type}-y${idx.toString()}`;
const color = coldata.map((value, index) =>
getBackgroundColor(
customStyleConfig,
visualProps,
idx,
dataArr,
CFforColumn,
index,
col.id
)
);
return {
label: col.name,
data: coldata,
yAxisID: axisId,
type: `${type}`,
backgroundColor: color,
borderColor: color,
datalabels: {
anchor: "end",
},
};
}),
getScales: () =>
_.reduce(
yAxisColumns,
(obj: any, _val, idx: number) => {
// eslint-disable-next-line no-param-reassign
obj[`${type}-y${idx.toString()}`] = {
grid: {
display: true,
},
position: idx === 0 ? "left" : "right",
title: {
display: true,
text: _val.name,
},
};
return obj;
},
{}
),
getPointDetails: (xPos: number, yPos: number): PointVal[] => [
{
columnId: xAxisColumns[0].id,
value: getDataForColumn(xAxisColumns[0], dataArr)[xPos],
},
{
columnId: yAxisColumns[yPos].id,
value: getDataForColumn(yAxisColumns[yPos], dataArr)[xPos],
},
],
};
}
- In the above implementation you will be getting error inside
getPointsdetailsbeacuse we have a undefined functiongetDataForColumn. This function will take the column ids and return the specific cloumn data. Implement this function in with the following code snippet->
function getDataForColumn(column: ChartColumn, dataArr: DataPointsArray) {
const idx = _.findIndex(dataArr.columns, (colId) => column.id === colId);
return _.map(dataArr.dataValue, (row) => row[idx]);
}
-
In the above implementation, you will need to implement the following functions to ensure that the conditional formatting and background colors are correctly applied, and that the plotlines and plotbands are drawn on the chart.
getBackgroundColor: This function determines the background color for each data point based on custom style configurations, visual properties, and any applicable conditional formatting rules. Implement this function with the following code snippet:export function getBackgroundColor( customStyleConfig: ChartSdkCustomStylingConfig, visualProps: VisualProps, idx: any, dataArr: any, CFforColumn: any, index: number, colId: any ) { const color = customStyleConfig?.chartColorPalettes?.length && customStyleConfig?.chartColorPalettes[0].colors.length > 0 ? customStyleConfig?.chartColorPalettes[0].colors : _.get(visualProps, visualPropKeyMap?.[idx], availableColor[idx]); return color; }